import { EtcdRegisterService } from '@app/etcd-register';
import { FormatService } from '@app/format';
import { NacosRegisterService } from '@app/nacos-register';
import getAuthExceptions from '@app/router/authMaps';
import isRoutesAllowed from '@app/router/routerMaps';
import reqData from '@app/utils/reqData';
import { Inject, Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { ClientProxy } from '@nestjs/microservices';

@Injectable()
export class GatewayService {
  @Inject(FormatService)
  formatService: FormatService;

  @Inject(JwtService)
  jwtService: JwtService;

  @Inject('COMMON_SERVICE')
  commonServiceClient: ClientProxy;

  @Inject('USER_SERVICE')
  userServiceClient: ClientProxy;

  @Inject(NacosRegisterService)
  nacosRegisterService: NacosRegisterService;

  @Inject(EtcdRegisterService)
  etcdRegisterService: EtcdRegisterService;
  async TCPtranspond(query: any, body: any, request: any) {
    /**
     *  处理数据
     */
    const req = reqData(request);

    /**
     *  动态判断请求服务
     * 服务发现,服务是否在线
     */
    let targetClient: ClientProxy | null = null;
    // nacos
    const result1 = await this.nacosRegisterService.getAllService();
    for (const i of result1) {
      if (`${req.service}-service` === i.name && i.status) {
        if (i.name === 'user-service') {
          targetClient = this.userServiceClient;
        } else if (i.name === 'common-service') {
          targetClient = this.commonServiceClient;
        }
        break;
      }
    }

    if (!targetClient) {
      return this.formatService.error('Nacos 微服务不存在或不在线', 504);
    }
    // etcd
    const result2 = await this.etcdRegisterService.getAllService();
    for (const i of result2) {
      if (`${req.service}-service` === i.name && i.status) {
        if (i.name === 'user-service') {
          targetClient = this.userServiceClient;
        } else if (i.name === 'common-service') {
          targetClient = this.commonServiceClient;
        }
        break;
      }
    }

    if (!targetClient) {
      return this.formatService.error('Etcd 微服务不存在或不在线', 504);
    }

    /**
     *  路由表校验
     */
    const allowedRoute = isRoutesAllowed(req.service, req.method, req.path);
    if (!allowedRoute.status) {
      return this.formatService.error(allowedRoute.msg, allowedRoute.code);
    }

    /**
     * JWT 鉴权
     */

    const noAuthRequiredRoutes = getAuthExceptions(req.service);
    const isNoAuthRequired = noAuthRequiredRoutes.some(
      (route: any) => route.method === req.method && route.path === req.path,
    );
    if (!isNoAuthRequired) {
      const authorization = request.headers.authorization;

      if (!authorization) {
        return this.formatService.error('用户未登录', 401);
      }

      try {
        const token = authorization.split(' ')[1];
        const secret = 'hh2837183';
        const decodedUser = this.jwtService.verify(token, { secret }); // 验证 token
        request.user = decodedUser;
      } catch (error) {
        return this.formatService.error('token 失效，请重新登录', 402);
      }
    }
    /**
     * 业务权限 校验
     */

    /**
     *  通过 TCP 向目标服务发送请求，并封装响应数据
     *  将所有参数打包传递到目标微服务
     */
    const allParams = {
      method: req.method, // HTTP 请求方法
      path: req.path, // 请求的路径
      query: query, // URL 查询参数
      body: body, // 请求体参数
      params: req.params, // 路径参数
    };

    try {
      const result = await targetClient
        .send(`${req.method.toLowerCase()}-${req.path}`, allParams)
        .toPromise();
      return this.formatService.success(result);
    } catch (error) {
      console.log(error);
      return this.formatService.error('TCP转发错误', 500);
    }
  }
}
